package com.aefottt.struggle_star.view;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AnticipateInterpolator;
import android.view.animation.OvershootInterpolator;

import androidx.annotation.Nullable;
import androidx.core.content.res.ResourcesCompat;

import com.aefottt.struggle_star.R;

import java.util.Objects;

public class AchieveView extends View {
    public static final int ACHIEVED_STATE = 0;
    public static final int NOT_ACHIEVED_STATE = 1;

    final int color = getResources().getColor(R.color.themeColor);
    final int strokeWidth = 6;

    // 是否可以点击
    private boolean canClick;
    // 是否已完成
    private boolean isAchieved;
    // 中心XY坐标
    private float centerX, centerY;
    // 半径
    private float radius, whiteCircleRadius;
    // Hook缩放比例
    private float hookScale;
    // HookBitmap的left和top属性
    private float hookLeft, hookTop;

    // 已完成画笔
    private final Paint achievedPaint = new Paint();
    private final Paint whiteCirclePaint = new Paint();
    private final Paint hookPaint = new Paint();
    private final Paint notAchievedPaint = new Paint();

    // 对勾图标
    private Bitmap hookBitmap;

    private OnAchievedViewListener onAchievedViewListener;

    public AchieveView(Context context) {
        super(context);
    }

    public AchieveView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
        setClickable(true);
    }

    private void init(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.AchieveView);
        canClick = typedArray.getBoolean(R.styleable.AchieveView_canClick, true);
        typedArray.recycle();

        achievedPaint.setColor(color);
        notAchievedPaint.setStyle(Paint.Style.STROKE);
        notAchievedPaint.setColor(Color.GRAY);
        notAchievedPaint.setStrokeWidth(strokeWidth);
        notAchievedPaint.setAntiAlias(true);
        whiteCirclePaint.setColor(Color.WHITE);
        whiteCirclePaint.setAntiAlias(true);
        whiteCirclePaint.setDither(true);

        hookBitmap = ((BitmapDrawable) Objects.requireNonNull(ResourcesCompat.
                getDrawable(getResources(), R.drawable.hook, null))).getBitmap();
        hookScale = isAchieved ? 1.0f : 0;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        centerX = (float) getMeasuredWidth() / 2;
        centerY = (float) getMeasuredHeight() / 2;
        radius = (float) getMeasuredWidth() / 2 - strokeWidth;

        hookLeft = radius - (float) hookBitmap.getWidth() / 2 + strokeWidth;
        hookTop = radius - (float) hookBitmap.getHeight() / 2 + strokeWidth;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 已完成画实心color圆，未完成画空心圆
        canvas.drawCircle(centerX, centerY, radius, isAchieved ? achievedPaint : notAchievedPaint);
        // 画勾
        canvas.save();
        canvas.scale(hookScale, hookScale, radius, radius);
        canvas.drawBitmap(hookBitmap, hookLeft, hookTop, hookPaint);
        canvas.restore();
        // 画有填充动画效果的白圆
        canvas.drawCircle(centerX, centerY, whiteCircleRadius, whiteCirclePaint);
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!canClick) {
            return false;
        }
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_UP:
                Log.e(getClass().getName(), "ACTION_UP");
                if (isAchieved) {
                    // 点击后未完成
                    notAchievedPaint.setStyle(Paint.Style.STROKE);
                    notAchievedPaint.setColor(Color.GRAY);
                    notAchievedPaint.setStrokeWidth(strokeWidth);
                    startNotAchievedAnim();
                } else {
                    // 点击后已完成
                    notAchievedPaint.setStyle(Paint.Style.FILL);
                    notAchievedPaint.setColor(color);
                    startAchievedAnim();
                }
                break;
        }
        return super.onTouchEvent(event);
    }

    /**
     * 未完成->已完成的动画
     */
    private void startAchievedAnim() {
        ObjectAnimator animator1 = ObjectAnimator.ofFloat(this,
                "whiteCircleRadius", radius - strokeWidth, 0);
        ObjectAnimator animator2 = ObjectAnimator.ofFloat(this, "hookScale", 0, 1.0f);
        animator2.setInterpolator(new OvershootInterpolator()); // 回弹
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playSequentially(animator1, animator2);
        animatorSet.setDuration(400);
        animatorSet.start();
        animatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                isAchieved = true;
                if (onAchievedViewListener != null) {
                    // 完成后的回调
                    onAchievedViewListener.onAchieved(ACHIEVED_STATE);
                }
            }
        });
    }

    /**
     * 已完成->未完成的动画
     */
    private void startNotAchievedAnim() {
        ObjectAnimator animator1 = ObjectAnimator.ofFloat(this,
                "whiteCircleRadius", 0, radius - strokeWidth);
        ObjectAnimator animator2 = ObjectAnimator.ofFloat(this, "hookScale", 1.0f, 0);
        animator2.setInterpolator(new AnticipateInterpolator()); // 先后撤再回弹
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playSequentially(animator2, animator1);
        animatorSet.setDuration(300);
        animatorSet.start();
        animatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                isAchieved = false;
                if (onAchievedViewListener != null) {
                    // 完成后的回调
                    onAchievedViewListener.onAchieved(NOT_ACHIEVED_STATE);
                }
            }
        });
    }

    public void setAchieved(int achieved) {
        isAchieved = achieved == 1;
        hookScale = isAchieved ? 1.0f : 0;
        invalidate();
    }

    public interface OnAchievedViewListener {
        void onAchieved(int state);
    }

    public float getWhiteCircleRadius() {
        return whiteCircleRadius;
    }

    public void setWhiteCircleRadius(float whiteCircleRadius) {
        this.whiteCircleRadius = whiteCircleRadius;
        invalidate();
    }

    public float getHookScale() {
        return hookScale;
    }

    public void setHookScale(float hookScale) {
        this.hookScale = hookScale;
        invalidate();
    }

    public void setCanClick(boolean canClick) {
        this.canClick = canClick;
    }

    public void setOnAchievedViewListener(OnAchievedViewListener onAchievedViewListener) {
        this.onAchievedViewListener = onAchievedViewListener;
    }
}
